package com.linkgie.galaxyframework.utils.image.qr;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;

import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.linkgie.galaxyframework.utils.RuntimeIOException;

public class QRCodeUtils {

    public static final String DEFAULT_CHARSET = "utf-8";

    // 二维码尺寸
    private static final int QRCODE_SIZE = 300;

    public static BufferedImage generateImage(String content) {
        return generateImage(content, DEFAULT_CHARSET);
    }

    public static BufferedImage generateImage(String content, int size) {
        return generateImage(content, DEFAULT_CHARSET, size);
    }

    public static BufferedImage generateImage(String content, String charset) {
        return generateImage(content, charset, QRCODE_SIZE);
    }

    /**
     * 生成二维码图片；
     * 
     * @param content
     * @param size
     * @param charset
     * @return
     */
    public static BufferedImage generateImage(String content, String charset, int size) {
        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, charset);
        hints.put(EncodeHintType.MARGIN, 1);
        BitMatrix bitMatrix = null;
        try {
            bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, size, size,
                    hints);
        } catch (WriterException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
        int width = bitMatrix.getWidth();
        int height = bitMatrix.getHeight();
        // BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 采用 RGB 模式，不包含透明色定义；
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, bitMatrix.get(x, y) ? 0x00000000 : 0xFFFFFFFF);
            }
        }
        return image;
    }

    /**
     * 生成二维码图片，输出到字节流；
     * 
     * @param imageFormat 图片格式；例如: png，jpg 等；
     * @param output      输出流；
     * @throws IOException
     */
    public static void generateImage(String content, String imageFormat, OutputStream output) {
        generateImage(content, QRCODE_SIZE, imageFormat, output);
    }

    /**
     * 生成二维码图片，输出到字节流；
     * 
     * @param content     编码到二维码中的内容；
     * @param size        图片的长宽大小，单位：像素；
     * @param imageFormat 图片格式；例如: png，jpg 等；
     * @param output      输出流；
     * @throws IOException
     */
    public static void generateImage(String content, int size, String imageFormat, OutputStream output) {
        generateImage(content, DEFAULT_CHARSET, size, imageFormat, output);
    }

    /**
     * 生成二维码图片，输出到字节流；
     * 
     * @param content     编码到二维码中的内容；
     * @param chartset    字符集
     * @param size        图片的长宽大小，单位：像素；
     * @param imageFormat 图片格式；例如: png，jpg 等；
     * @param output      输出流；
     * @throws IOException
     */
    public static void generateImage(String content, String chartset, int size, String imageFormat,
            OutputStream output) {
        try {
            BufferedImage image = generateImage(content, chartset, size);
            ImageIO.write(image, imageFormat, output);
        } catch (IOException e) {
            throw new RuntimeIOException(e.getMessage(), e);
        }
    }

}